﻿#include "TurnTableCodec.h"

#include "MsgIdManager.h"
#include "TransmitCodec.h"
#include "TcpCodec.h"
#include "ScriptRunner.h"

#include "TurnTableDecodeBase.h"
#include "TurnTableDecode_TurnTable_Connect.h"
#include "TurnTableDecode_TurnTable_Disconnect.h"
#include "TurnTableDecode_Thermostat_CurrentTemperature.h"
#include "TurnTableDecode_TurnTable_CurrentState.h"
#include "TurnTableDecode_TurnTable_SearchZeroState.h"
#include "TurnTableDecode_TurnTable_RunningState.h"
#include "TurnTableDecode_TurnTable_RunningMode.h"
#include "TurnTableDecode_TurnTable_Error.h"

#include "TurnTableCode_TurnTable_Connect.h"
#include "TurnTableCode_TurnTable_Disconnect.h"
#include "TurnTableCode_TurnTable_SetLoad.h"
#include "TurnTableCode_TurnTable_PowerOn.h"
#include "TurnTableCode_TurnTable_PowerOff.h"
#include "TurnTableCode_TurnTable_CloseCircuit.h"
#include "TurnTableCode_TurnTable_OpenCircuit.h"
#include "TurnTableCode_TurnTable_Stop.h"
#include "TurnTableCode_TurnTable_EmergencyStop.h"
#include "TurnTableCode_TurnTable_SearchZero.h"
#include "TurnTableCode_TurnTable_MoveToZero.h"
#include "TurnTableCode_TurnTable_SetPositionMode.h"
#include "TurnTableCode_TurnTable_SetRateMode.h"
#include "TurnTableCode_TurnTable_Run.h"
#include "TurnTableCode_TurnTable_CurrentState.h"
#include "TurnTableCode_TurnTable_SearchZeroState.h"
#include "TurnTableCode_TurnTable_RunningState.h"
#include "TurnTableCode_TurnTable_RunningMode.h"
#include "TurnTableCode_Thermostat_Connect.h"
#include "TurnTableCode_Thermostat_Disconnect.h"
#include "TurnTableCode_Thermostat_TargetTemperature.h"
#include "TurnTableCode_Thermostat_CurrentTemperature.h"
#include "TurnTableCode_Thermostat_TemperatureRate.h"
#include "TurnTableCode_TurnTable_QuitConsole.h"

TurnTableCodec::TurnTableCodec()//构造函数
{
  turnTableDecodeMap.insert(TurnTable_Connect,new TurnTableDecode_TurnTable_Connect(this));
  turnTableDecodeMap.insert(TurnTable_Disconnect,new TurnTableDecode_TurnTable_Disconnect(this));
  turnTableDecodeMap.insert(Thermostat_CurrentTemperature,new TurnTableDecode_Thermostat_CurrentTemperature(this));
  turnTableDecodeMap.insert(TurnTable_CurrentState,new TurnTableDecode_TurnTable_CurrentState(this));
  turnTableDecodeMap.insert(TurnTable_SearchZeroState,new TurnTableDecode_TurnTable_SearchZeroState(this));
  turnTableDecodeMap.insert(TurnTable_RunningState,new TurnTableDecode_TurnTable_RunningState(this));
  turnTableDecodeMap.insert(TurnTable_RunningMode,new TurnTableDecode_TurnTable_RunningMode(this));
  turnTableDecodeMap.insert(TurnTable_Error,new TurnTableDecode_TurnTable_Error(this));

  turnTableCodeMap.insert(TurnTable_Connect,new TurnTableCode_TurnTable_Connect());
  turnTableCodeMap.insert(TurnTable_Disconnect,new TurnTableCode_TurnTable_Disconnect());
  turnTableCodeMap.insert(TurnTable_SetLoad,new TurnTableCode_TurnTable_SetLoad());
  turnTableCodeMap.insert(TurnTable_PowerOn,new TurnTableCode_TurnTable_PowerOn());
  turnTableCodeMap.insert(TurnTable_PowerOff,new TurnTableCode_TurnTable_PowerOff());
  turnTableCodeMap.insert(TurnTable_CloseCircuit,new TurnTableCode_TurnTable_CloseCircuit());
  turnTableCodeMap.insert(TurnTable_OpenCircuit,new TurnTableCode_TurnTable_OpenCircuit());
  turnTableCodeMap.insert(TurnTable_Stop,new TurnTableCode_TurnTable_Stop());
  turnTableCodeMap.insert(TurnTable_EmergencyStop,new TurnTableCode_TurnTable_EmergencyStop());
  turnTableCodeMap.insert(TurnTable_SearchZero,new TurnTableCode_TurnTable_SearchZero());
  turnTableCodeMap.insert(TurnTable_MoveToZero,new TurnTableCode_TurnTable_MoveToZero());
  turnTableCodeMap.insert(TurnTable_SetPositionMode,new TurnTableCode_TurnTable_SetPositionMode(this));
  turnTableCodeMap.insert(TurnTable_SetRateMode,new TurnTableCode_TurnTable_SetRateMode(this));
  turnTableCodeMap.insert(TurnTable_Run,new TurnTableCode_TurnTable_Run());
  turnTableCodeMap.insert(TurnTable_CurrentState,new TurnTableCode_TurnTable_CurrentState());
  turnTableCodeMap.insert(TurnTable_SearchZeroState,new TurnTableCode_TurnTable_SearchZeroState());
  turnTableCodeMap.insert(TurnTable_RunningState,new TurnTableCode_TurnTable_RunningState());
  turnTableCodeMap.insert(TurnTable_RunningMode,new TurnTableCode_TurnTable_RunningMode());
  turnTableCodeMap.insert(Thermostat_Connect,new TurnTableCode_Thermostat_Connect());
  turnTableCodeMap.insert(Thermostat_Disconnect,new TurnTableCode_Thermostat_Disconnect());
  turnTableCodeMap.insert(Thermostat_TargetTemperature,new TurnTableCode_Thermostat_TargetTemperature());
  turnTableCodeMap.insert(Thermostat_CurrentTemperature,new TurnTableCode_Thermostat_CurrentTemperature());
  turnTableCodeMap.insert(Thermostat_TemperatureRate,new TurnTableCode_Thermostat_TemperatureRate());
  turnTableCodeMap.insert(TurnTable_QuitConsole,new TurnTableCode_TurnTable_QuitConsole());
}

TurnTableCodec::~TurnTableCodec()
{
  for(int key:turnTableDecodeMap.keys())
    {
      delete turnTableDecodeMap.take(key);
    }
  for(int key:turnTableCodeMap.keys())
    {
      delete turnTableCodeMap.take(key);
    }
}

void TurnTableCodec::sendInstruction(uint deviceId, uint userId, TurnTableInstructionFlag instructionFlag, float arg1, float arg2, float arg3)
{
  if(turnTableCodeMap.contains(instructionFlag))
    {
      QByteArray result=turnTableCodeMap.value(instructionFlag)->code(arg1,arg2,arg3);
      if(!result.isEmpty())//结果不为空则说明编码无误
        {
          lastUserIdByDeviceIdMap.insert(deviceId,userId);//插入设备和用户，返回错误时转发
          qDebug()<<"turntable data:"<<result.toHex();
          transmitCodec->decode_tcp(deviceId,userId,TcpCodec::TurnTable,result);//发送编码后的数据
          return;
        }
    }
  //意外情况返回数据错误反馈
  if(ScriptRunner::userId_scriptRunner==userId)
    {
//      scriptRunner->handleTransmitResult(TransmitCodec::ErrorData);
    }
  else
    {
      tcpCodec->code(userId, TcpCodec::Transmit, QByteArray().append(TransmitCodec::ErrorData));
    }
  return;
}

uchar TurnTableCodec::getType(QByteArray data)
{
  return (uchar)data.at(0);
}

void TurnTableCodec::decode(QByteArray instruction, uint deviceId)
{
  if(instruction.size()!=dataPackageSize)//若数据包大小不等于转台数据包大小则代表错误的格式，直接返回
    {
      return;
    }
  if (instruction.at(0) != (char)TurnTable_DeviceNum)//数据头不正确，直接返回
    {
      return;
    }
  uchar total = 0;
  for (int i = 0; i < dataPackageSize; i++)//计算检查和
    {
      total += (uchar)instruction.at(i);
    }
  if (total != 0)//检查和结果不为0则代表出错，直接返回
    {
      return ;
    }
  uchar type=instruction.at(2);
  if(turnTableDecodeMap.contains(type))
    {
      turnTableDecodeMap.value(type)->decode(instruction.data(),deviceId);
    }
}

uint TurnTableCodec::getLastUserIdByDeviceId(uint deviceId,bool* isOk)
{
  if(lastUserIdByDeviceIdMap.contains(deviceId))
    {
      *isOk=true;
      return lastUserIdByDeviceIdMap.value(deviceId);
    }
  else
    {
      *isOk=false;
      return 0;
    }
}

float TurnTableCodec::getTurnTablePositionUpperLimit()
{
  return turnTablePositionUpperLimit;
}
TurnTableCodec* TurnTableCodec::setTurnTablePositionUpperLimit(float turnTablePositionUpperLimit)
{
  this->turnTablePositionUpperLimit=turnTablePositionUpperLimit;
  return this;
}
float TurnTableCodec::getTurnTablePositionLowerLimit()
{
  return turnTablePositionLowerLimit;
}
TurnTableCodec* TurnTableCodec::setTurnTablePositionLowerLimit(float turnTablePositionLowerLimit)
{
  this->turnTablePositionLowerLimit = turnTablePositionLowerLimit;
  return this;
}
float TurnTableCodec::getTurnTableRateUpperLimit()
{
  return turnTableRateUpperLimit;
}
TurnTableCodec* TurnTableCodec::setTurnTableRateUpperLimit(float turnTableRateUpperLimit)
{
  this->turnTableRateUpperLimit = turnTableRateUpperLimit;
  return this;
}
float TurnTableCodec::getTurnTableRateLowerLimit()
{
  return turnTableRateLowerLimit;
}
TurnTableCodec* TurnTableCodec::setTurnTableRateLowerLimit(float turnTableRateLowerLimit)
{
  this->turnTableRateLowerLimit = turnTableRateLowerLimit;
  return this;
}

float TurnTableCodec::getTurnTableAccelerationUpperLimit()
{
  return turnTableAccelerationUpperLimit;
}

TurnTableCodec* TurnTableCodec::setTurnTableAccelerationUpperLimit(float turnTableAccelerationUpperLimit)
{
  this->turnTableAccelerationUpperLimit = turnTableAccelerationUpperLimit;
  return this;
}

float TurnTableCodec::getTurnTableAccelerationLowerLimit()
{
  return turnTableAccelerationLowerLimit;
}

TurnTableCodec *TurnTableCodec::setTurnTableAccelerationLowerLimit(float turnTableAccelerationLowerLimit)
{
  this->turnTableAccelerationLowerLimit = turnTableAccelerationLowerLimit;
  return this;
}

TransmitCodec* TurnTableCodec::getTransmitCodec()const
{
  return transmitCodec;
}

TurnTableCodec* TurnTableCodec::setTransmitCodec(TransmitCodec*const transmitCodec)
{
  this->transmitCodec=transmitCodec;
  printInjection(this,transmitCodec);
  return this;
}

TcpCodec* TurnTableCodec::getTcpCodec()const
{
  return tcpCodec;
}

TurnTableCodec* TurnTableCodec::setTcpCodec(TcpCodec*const tcpCodec)
{
  this->tcpCodec=tcpCodec;
  printInjection(this,tcpCodec);
  return this;
}

ScriptRunner* TurnTableCodec::getScriptRunner()const
{
  return scriptRunner;
}

TurnTableCodec* TurnTableCodec::setScriptRunner(ScriptRunner*const scriptRunner)
{
  this->scriptRunner=scriptRunner;
  printInjection(this,scriptRunner);
  return this;
}

void TurnTableCodec::objectAutoInjection(QHash<QString,QObject*>* objMap)
{
  setTransmitCodec(getObjFromMap<TransmitCodec>(objMap));
  setTcpCodec(getObjFromMap<TcpCodec>(objMap));
  setScriptRunner(getObjFromMap<ScriptRunner>(objMap));
  for(int key:turnTableDecodeMap.keys())
    {
      ObjAutoInject* objAutoInject=dynamic_cast<ObjAutoInject*>(turnTableDecodeMap.value(key));
      if(objAutoInject)
        {
          objAutoInject->objectAutoInjection(objMap);
        }
    }
}
